package com.lmpop.createIndex.searchModel;

import java.io.File;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Hashtable;
import java.util.List;
import java.util.Map;

import org.apache.lucene.analysis.Analyzer;
import org.apache.lucene.analysis.standard.StandardAnalyzer;
import org.apache.lucene.document.Document;
import org.apache.lucene.document.Field;
import org.apache.lucene.index.IndexReader;
import org.apache.lucene.index.Term;
import org.apache.lucene.queryParser.MultiFieldQueryParser;
import org.apache.lucene.queryParser.ParseException;
import org.apache.lucene.queryParser.QueryParser;
import org.apache.lucene.search.BooleanClause;
import org.apache.lucene.search.BooleanQuery;
import org.apache.lucene.search.Hits;
import org.apache.lucene.search.IndexSearcher;
import org.apache.lucene.search.Query;
import org.apache.lucene.search.RangeQuery;
import org.apache.lucene.search.Searcher;

public class SearchData
{
  LinkInterf linkInterf;
  KeywordFilter keyFilter;
  String rootpath = "";

  public SearchData() {
    this.linkInterf = new LinkInterf();
    this.keyFilter = new KeywordFilter();
    this.rootpath = this.linkInterf.getConfigString("rootpath");
  }

  public Map getSearchObject(String file_path, ArrayList paraList) throws IOException {
    ArrayList infoList = getSearchInfo(file_path, paraList);
    Map infoMap = new Hashtable();
    if ((infoList != null) && (infoList.size() > 0)) {
      infoMap = (Hashtable)infoList.get(0);
    }
    return infoMap;
  }

  public ArrayList getSearchInfo(String file_path, ArrayList paraList) throws IOException {
    Queue queue = new Queue(new QueueValue[] { new QueueValue("all", 2, true) });
    return getSearchInfo(file_path, paraList, queue);
  }

  public ArrayList getSearchInfo(String file_path, ArrayList paraList, Queue queue)
  {
    try {
      file_path = this.rootpath + file_path;
      ArrayList keyList = new ArrayList();
      if (!new File(file_path).exists()) {
        return null;
      }
      IndexReader reader = IndexReader.open(file_path);
      BooleanClause.Occur[] flags = { BooleanClause.Occur.SHOULD, BooleanClause.Occur.SHOULD };
      Searcher searcher = new IndexSearcher(reader);
      Analyzer analyzer = new StandardAnalyzer();
      BooleanQuery query = new BooleanQuery();
      BooleanQuery.setMaxClauseCount(10000);

      if ((paraList != null) && (paraList.size() > 0)) {
        for (int i = 0; i < paraList.size(); i++) {
          SearchModel smodel = (SearchModel)paraList.get(i);
          String fieldName = ""; String fieldValue = ""; String fieldType = ""; String fieldValue1 = "";
          String[] searchStr = smodel.getSearchStr();
          if (smodel.getFieldName() != null) fieldName = smodel.getFieldName();
          if (smodel.getFieldValue() != null) {
            fieldValue = smodel.getFieldValue();
          }

          if (smodel.getFieldValue1() != null) fieldValue1 = smodel.getFieldValue1();
          if (smodel.getSearchType() != null) fieldType = smodel.getSearchType();
          if (fieldValue.equals("")) {
            continue;
          }
          Query query_g = null;
          RangeQuery dateQuery = null;
          QueryParser parser = null;

          if (fieldType.equals("0")) {
            parser = new QueryParser(fieldName, analyzer);
            try {
              query_g = parser.parse(fieldValue);
            } catch (ParseException e) {
              e.printStackTrace();
            }
            query.add(query_g, BooleanClause.Occur.MUST);
          }
          if (fieldType.equals("1")) {
            dateQuery = new RangeQuery(new Term(fieldName, fieldValue), null, true);
            query.add(dateQuery, BooleanClause.Occur.MUST);
          }
          if (fieldType.equals("2")) {
            try {
              query_g = MultiFieldQueryParser.parse(fieldValue, searchStr, flags, analyzer);
            } catch (ParseException e) {
              e.printStackTrace();
            }
            query.add(query_g, BooleanClause.Occur.MUST);
          }
          if (fieldType.equals("3")) {
            dateQuery = new RangeQuery(new Term(fieldName, fieldValue), new Term(fieldName, fieldValue1), true);
            query.add(dateQuery, BooleanClause.Occur.MUST);
          }

        }

      }

      Query query_all = null;
      Hits hits = null;
      QueryParser parser_all = new QueryParser("all", analyzer);
      try {
        query_all = parser_all.parse("allinfo");
        query.add(query_all, BooleanClause.Occur.MUST);

        if (queue == null)
          hits = searcher.search(query);
        else
          hits = searcher.search(query, queue);
      }
      catch (ParseException e) {
        e.printStackTrace();
      }

      if (hits == null) return null;

      for (int i = 0; i < hits.length(); i++){
        Document doc = hits.doc(i);
        List fieldList = doc.getFields();
        Hashtable map = new Hashtable();
        for (int j = 0; j < fieldList.size(); j++) {
          Field field = (Field)fieldList.get(j);
          String fieldName = field.name();
          String fieldValue = field.stringValue();
          map.put(fieldName, fieldValue);
        }
        keyList.add(map);
      }
      reader.close();
      return keyList;
    } catch (Exception e) {
      e.printStackTrace();
    }
    return null;
  }
}